package com.fruit.account.service.commission;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.alibaba.fastjson.JSONObject;
import com.fruit.account.common.CommMsgUtil;
import com.fruit.account.service.excommission.CommBackLogServiceImpl;
import com.fruit.constants.BillConstant;
import com.fruit.mapper.account.balance.BalanceDetailMapper;
import com.fruit.mapper.account.commission.CommissionDetailMapper;
import com.fruit.mapper.account.repeat.ActivityRepeatDetailMapper;
import com.fruit.mapper.account.ticket.TicketDetailMapper;
import com.fruit.mapper.account.transaction.TransactionFlowPoMapper;
import com.fruit.mapper.account.user.UserAccountMapper;
import com.fruit.mapper.account.voucher.ActivityVoucherMapper;
import com.fruit.pojo.account.balance.BalanceDetail;
import com.fruit.pojo.account.commission.CommissionDetail;
import com.fruit.pojo.account.excommission.ExceptionCommission;
import com.fruit.pojo.account.repeat.ActivityRepeatDetail;
import com.fruit.pojo.account.repeat.RepeatInfo;
import com.fruit.pojo.account.ticket.TicketDetail;
import com.fruit.pojo.account.transaction.TransactionFlowPo;
import com.fruit.pojo.account.user.UserAccount;
import com.fruit.pojo.account.voucher.ActivityVoucher;
import com.fruit.pojo.promotion.ActivityRule;
import com.fruit.pojo.promotion.ActivityUserInfo;
import com.fruit.pojo.promotion.ActivityUserRelation;
import com.fruit.pojo.push.Message;
import com.fruit.pojo.user.UserInfo;
import com.fruit.pojo.user.sysmsg.SysMessage;
import com.fruit.sdk.account.commission.MultilevelRebateService;
import com.fruit.service.promotion.ActivityManager;
import com.fruit.service.promotion.ActivityRuleManager;
import com.fruit.service.push.AppPushService;
import com.fruit.service.sysmsg.SysMessageService;
import com.fruit.service.user.UserManager;
import com.fruit.util.CustomUtil;
import com.fruit.util.DateUtil;
import com.fruit.util.ResultInfo;
import com.fruit.util.ResultUtil;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 * 分润业务相关Service
 *
 * @author Administrator
 * @version 2018.01.08 10:16
 */
@Slf4j
@Service("multilevelRebateService")
public class MultilevelRebateServiceImpl implements MultilevelRebateService {
	@Autowired
	private UserManager userService;
	@Autowired
	private TransactionFlowPoMapper transactionFlowPoMapper;
	@Autowired
	private CommissionDetailMapper commissionDetailMapper;
	@Autowired
	private BalanceDetailMapper balanceDetailMapper;
	@Autowired
	private UserAccountMapper userAccountMapper;
	@Autowired
	private SysMessageService sysMessageService;
	@Autowired
	private CommBackLogServiceImpl commBackLogServiceImpl;
	@Value("${h5_domain}")
	private String h5Domain;

	@Autowired
	private AppPushService appPushService;

	@Autowired
	private ActivityRuleManager activityRuleService;
	@Autowired
	private ActivityRepeatDetailMapper activityRepeatDetailMapper;
	@Autowired
	private TicketDetailMapper ticketDetailMapper;
	@Autowired
	private ActivityManager activityService;
	@Autowired
	private ActivityVoucherMapper activityVoucherMapper;
	
	@Data
	class Rule {
		private BigDecimal oneRate = null;// 直推奖比例（占消费金额的比例）
		private BigDecimal oneAmount = null;// 直推奖金额
		private BigDecimal oneUserRate = null; // 用户直推奖比率（占直推奖的比例）
		private BigDecimal oneUserAmount = null;// 用户直推奖励金额
		private BigDecimal onePointsRate = null; // 直推粮票比例
		private BigDecimal onePoints = null;// 直推粮票
		private BigDecimal oneServiceRate = null; // 直推手续费比例
		private BigDecimal oneServiceAmount = null;// 直推手续费
		private BigDecimal oneRepeatRate = null;// 直推复投比例
		private BigDecimal oneRepeatAmount = null;// 直推复投金额

		private BigDecimal twoRate = null;// 间推奖比例（占消费金额的比例）
		private BigDecimal twoAmount = null;// 间推奖金额
		private BigDecimal twoUserRate = null;// 用户间推奖比率（占间推奖的比例）
		private BigDecimal twoUserAmount = null;// 用户间推奖励金额
		private BigDecimal twoPointsRate = null; // 间推粮票比率
		private BigDecimal twoPoints = null;// 间推粮票
		private BigDecimal twoServiceRate = null; // 间推手续费比例
		private BigDecimal twoServiceAmount = null;// 间推手续费
		private BigDecimal twoRepeatRate = null;// 间推复投比例
		private BigDecimal twoRepeatAmount = null;// 间推复投金额		

		private BigDecimal indirectRate = null;// 见点奖比例（占消费金额的比例）
		private BigDecimal indirectAmount = null;// 见点金额
		private BigDecimal indirectUserRate = null;// 用户见点奖比例（占见点金额的比例）
		private BigDecimal indirectUserAmount = null;// 用户见点金额
		private BigDecimal indirectPointsRate = null;// 见点粮票比例
		private BigDecimal indirectPoints = null;// 见点粮票
		private BigDecimal indirectServiceRate = null;// 见点手续费比例
		private BigDecimal indirectServiceAmount = null;// 见点手续费
		private BigDecimal indirectRepeatRate = null;// 见点复投比例
		private BigDecimal indirectRepeatAmount = null;// 见点复投金额
		
		private BigDecimal indirectAccLimit = null; // 见点返利累计上限
		private Map<String,PointRule> indirectMap = new HashMap<>(); //见点档次集合
		
		//公排规则
//		private String[] pubOrder = null;
		
		private BigDecimal repeatLimit = null; // 复投阈值
		private BigDecimal repeatLimitValue = null; // 复投阈值对应复投金额
		private Integer repeatGoodsId = null; // 复投虚拟商品id
		private List<RepeatInfo> repeatInfos = new ArrayList<RepeatInfo>(); // 复投信息列表
		private Set<Integer> upSet = new HashSet<>();

		private BigDecimal exchangeRate = null; // 粮票兑换比例
	}
	@Data 
	class PointRule { 
		private BigDecimal leveKey = null; //见点档次
		private BigDecimal ratio = null; //见点比率
		private Map<String,String> ratLimitMap = new HashMap<>(); //见点上限集合
		private String[] repPoints = null; // 复投点儿
	}

	@Override
	public Map<String, Object> doMultilevelRebate(String tradeId, Integer userId, BigDecimal price, Long billId,
			Integer activityId, Integer goodsId) {
		log.info("[" + tradeId + "]---【分润活动处理】---【开始params】---userId=" + userId + ";billId=" + billId
				+ ";activityId=" + activityId + ";goodsId=" + goodsId);
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			if (userId == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "param_error", "传入参数用户id不能为空!"));
				return result;
			}
			if (StringUtils.isEmpty(tradeId)) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "param_error", "日志流水号不能为空!"));
				return result;
			}
			if (billId == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "param_error", "交易订单id不能为空!"));
				return result;
			}
			if (activityId == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "param_error", "活动id不能为空!"));
				return result;
			}
			if (goodsId == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "param_error", "活动商品id不能为空!"));
				return result;
			}
			// 获取活动规则
			log.info("[" + tradeId + "]---【多级分润处理】---【获取活动规则】-----");
			List<ActivityRule> ruleList = getRules(tradeId, activityId, goodsId);
			if (ruleList == null || ruleList.size() <= 0) {
				log.info("[" + tradeId + "]---【多级分润处理】---【获取活动规则】-----【结果为null】");
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "ruleList_error", "获取活动规则失败!"));
				return result;
			}
			// 设置规则参数
			Map<String, Object> rpMap = setRuleParams(ruleList, price);
			if (rpMap == null) {
				result.put("result",
						(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "设置规则参数失败", "", "01"));
				return result;
			}
			ResultInfo rpRi = (ResultInfo) rpMap.get("result");
			if (ResultInfo.ERROR.equals(rpRi.getState())) {
				result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "rule_error",
						rpRi.getMessage(), "", "01"));
				return result;
			}
			Rule rule = (Rule) rpMap.get("rule");
			// 处理分润
			result = ((MultilevelRebateServiceImpl)AopContext.currentProxy()).insertMultilevelRebate(tradeId, rule, userId, price,billId, activityId, goodsId);
			ResultInfo re = (ResultInfo) result.get("result");
			if (ResultInfo.ERROR.equals(re.getState())) {
				log.info("【分润活动处理】---【分润处理】---【结果为】-----code={},msg={}", re.getCode(), re.getMessage());
				result.put("result",
						(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "error", "处理分润业务异常！", "", "01"));
				return result;
			}
			
			log.info("[" + tradeId + "]---【分润活动处理】---【分润处理】---【成功】-----");
			//调用再次复投
			((MultilevelRebateServiceImpl)AopContext.currentProxy()).newDoRepeat(tradeId,rule.getRepeatInfos());
			log.info("[" + tradeId + "]---【分润活动处理】---【再次复投】---【成功】-----");
			
			//调用公排收益累计
			((MultilevelRebateServiceImpl)AopContext.currentProxy()).newAddRete(tradeId,rule.getUpSet(), activityId);
			log.info("[" + tradeId + "]---【分润活动处理】---【公排收益累计】---【成功】-----");
			
			result.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "success", "操作成功!"));
		} catch (Exception e) {
			log.error("[" + tradeId + "]---【分润活动处理】---【异常】-----{}", e);
			result.put("result",
					(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "exception", "分润活动处理异常！", "", "01"));
		}
		log.info("[" + tradeId + "]---【分润活动处理】---【结束】-----{}", result.toString());
		return result;
	}
	/**
	 * 分润业务处理
	 * @param tradeId 流水号
	 * @param rule 规则
	 * @param userId 用户
	 * @param price 价格
	 * @param billId 账单标识
	 * @param activityId 活动id
	 * @param goodsId 活动商品
	 * @return Map<String, Object>
	 */
	public Map<String, Object> insertMultilevelRebate(String tradeId, Rule rule, Integer userId, BigDecimal price,
			Long billId, Integer activityId, Integer goodsId) {
		log.info("[" + tradeId + "]---【多级分润处理】---【开始params】---userId=" + userId + ";billId=" + billId
				+ ";activityId=" + activityId + ";goodsId=" + goodsId);
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			// 用户直推间推的上级
			int parentsNum = 2;
			log.info("[{}]---【多级分润处理】---【获取用户{}级上级】-----", tradeId, parentsNum);
			Map<String, Object> uuMap = userService.getUserMultistage(userId, activityId, parentsNum);
			if (uuMap == null) {
				log.error("【生成分润业务数据】---【获取用户多级上级】---【结果为null】-----");
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "userPanent_error", "获取用户 "+ parentsNum +"级上级异常!", "", "01"));
				return result;
			}
			ResultInfo uuRi = (ResultInfo) uuMap.get("result");
			if (ResultInfo.ERROR.equals(uuRi.getState())) {
				log.error("【获取用户{}级上级】---【失败】-----code={},msg={}", parentsNum, uuRi.getCode(), uuRi.getMessage());
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "userPanent_error1", "获取用户 "+ parentsNum +"级上级异常!", "", "01"));
				return result;
			}
			log.info("【多级分润处理】---【获取用户多级上级】---【结果为】-----{}", uuMap.toString());
			List<UserInfo> userList = (List<UserInfo>) uuMap.get("userList");
			// 处理分润
			result = insertRebate(userList, rule, price, userId, billId, activityId, goodsId);
			ResultInfo oneResult = (ResultInfo) result.get("result");
			if (ResultInfo.ERROR.equals(oneResult.getState())) {
				log.info("【多级分润处理】---【处理分润】---【结果为】-----code={},msg={}", oneResult.getCode(), oneResult.getMessage());
				result.put("result",
						(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "rebate_error1", "生成多级分润业务异常！", "", "01"));
				return result;
			}
			result.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "rebate_success", "分润业务操作成功"));
			return result;
		} catch (Exception e) {
			rule.getRepeatInfos().clear();
			log.error("[" + tradeId + "]---【分润处理】---【异常】-----{}", e);
			result.put("result",
					(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "rebate_exception", "分润业务处理异常！", "", "01"));
			return result;
		} finally {
			ResultInfo ri = (ResultInfo) result.get("result");
			if (ResultInfo.ROLLBACK.equals(ri.getIsRollBack())) {
				log.info("[" + tradeId + "]---【分润处理】---【异常事务回滚】---{}---{}", ri.getMessage(), ri.getCode());
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			}
			if (ResultInfo.ERROR.equals(ri.getState())) { // 设置异常记录信息
				log.info("[" + tradeId + "]---【分润处理】---【日志记录】---{}---{}", ri.getMessage(), ri.getCode());
				ExceptionCommission exc = new ExceptionCommission();
				exc.setTradeId(tradeId);
				exc.setUserId(userId);
				exc.setServiceName("multilevelRebateServiceImpl");
				JSONObject paJson = new JSONObject();
				paJson.put("tradeId", tradeId);
				paJson.put("userId", userId);
				paJson.put("billId", billId);
				paJson.put("activityId", activityId);
				paJson.put("goodsId", goodsId);
				exc.setInputParams(paJson.toString());
				exc.setQueryTime(DateUtil.getTime());
				exc.setErrorCode(ri.getCode());
				exc.setErrorMessage(ri.getMessage());
				exc.setReserve1("02"); // 多级
				saveErrLog(exc);
			}
			log.info("[" + tradeId + "]---【多级分润处理】---【结束】-----");
		}
	}

	/**
	 * 获取用户活动直推人数和解锁层级
	 * @param userId
	 * @param activityId 
	 * @param rule 规则
	 * @return
	 */
//	public Map<String, Object> getUserNumAndLeve(Integer userId, Integer activityId, Rule rule) {
//		log.info("【获取用户活动直推人数和解锁层级】---【开始】-----");
//		Map<String, Object> result = new HashMap<String, Object>();
//		try {
//			Map<String, Object> parm = new HashMap<String, Object>();
//			parm.put("activityId", activityId);
//			parm.put("userId", userId);
//			String tradeId = CommonUtil.getUUID();
//			Map<String, Object> userMap = activityRuleService.getUserChildsNum(parm, tradeId);
//			if (userMap == null) {
//				log.error("【获取用户活动直推人数】---【结果为null】-----");
//				result.put("result",
//						(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "user_child_error1", "获取活动用户直属下级人数失败", "", "01"));
//				return result;
//			}
//			log.info("【获取用户活动直推人数】---【结果为】-----{}", userMap.toString());
//			ResultInfo userRi = (ResultInfo) userMap.get("result");
//			if (ResultInfo.ERROR.equals(userRi.getState())) {
//				log.error("【获取用户活动直推人数】---【失败】-----code={},msg={}", userRi.getCode(), userRi.getMessage());
//				result.put("result",
//						(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "user_child_error", userRi.getMessage(), "", "01"));
//				return result;
//			}
//			log.info("【获取用户活动直推人数】---【成功】-----");
//			//获取下级人数
//			int nn = Integer.valueOf("" + userMap.get("num"));			
//			int len = rule.getPubOrder().length; // 规则数组长度
//			if(nn > rule.getPubOrder().length) {
//				result.put("leve",rule.getPubOrder()[len-1]);
//			} else {
//				result.put("leve",rule.getPubOrder()[nn]);
//			}
//			result.put("result",
//					(ResultInfo) ResultUtil.initResult(ResultInfo.SUCCESS, "user_child_leve_error", "操作成功"));
//			log.info("【获取用户活动直推人数和解锁层级】---【成功】-----");
//		} catch (Exception e) {
//			log.error("【获取用户活动直推人数和解锁层级】---【异常】-----{}", e);
//			result.put("result",
//					(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "user_child_leve_exception", "解锁层级异常！", "", "01"));
//		}
//		log.info("【获取用户活动直推人数和解锁层级】---【结束】-----");
//		return result;
//	}

	/**
	 * 获取活动规则
	 * 
	 * @param tradeId
	 *            流水号
	 * @param activityId
	 *            活动id
	 * @param goodsId
	 *            活动商品id
	 * @return List<ActivityRule>
	 */
	public List<ActivityRule> getRules(String tradeId, Integer activityId, Integer goodsId) {
		log.info("【获取活动规则】---【开始】-----");
		List<ActivityRule> list = null;
		try {
			Map<String, Object> parm = new HashMap<String, Object>();
			parm.put("activityId", activityId);
			parm.put("goodsId", goodsId);
			Map<String, Object> ruleMap = activityRuleService.getActivityRules(parm, tradeId);
			if (ruleMap == null) {
				log.error("【获取活动规则】---【结果为null】-----");
				return null;
			}
			log.info("【获取活动规则】---【结果为】-----{}", ruleMap.toString());
			ResultInfo ruleRi = (ResultInfo) ruleMap.get("result");
			if (ResultInfo.ERROR.equals(ruleRi.getState())) {
				log.error("【获取活动规则】---【失败】-----code={},msg={}", ruleRi.getCode(), ruleRi.getMessage());
			}
			list = (List<ActivityRule>) ruleMap.get("list");
			log.info("【获取活动规则】---【成功】-----");
		} catch (Exception e) {
			log.error("获取活动规则】---【异常】-----", e);
		}
		log.info("【获取活动规则】---【结束】-----");
		return list;
	}

	/**
	 * 设置活动规则参数
	 * 
	 * @param ruleList
	 *            规则列表
	 * @return Map<String, Object>
	 */
	public Map<String, Object> setRuleParams(List<ActivityRule> ruleList, BigDecimal price) {
		log.info("【设置活动规则参数】---【开始】-----");
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			Rule rule = new Rule();
			for (ActivityRule ru : ruleList) {
				if ("01".equals(ru.getCondition())) { // 直推奖比例
					rule.setOneRate(new BigDecimal(ru.getValue()));
				}
				if ("02".equals(ru.getCondition())) { // 用户直推奖比率（占直推奖的比例）
					rule.setOneUserRate(new BigDecimal(ru.getValue()));
				}
				if ("03".equals(ru.getCondition())) { // 直推粮票比例
					rule.setOnePointsRate(new BigDecimal(ru.getValue()));
				}
				if ("04".equals(ru.getCondition())) { // 直推手续费比例
					rule.setOneServiceRate(new BigDecimal(ru.getValue()));
				}
				if ("05".equals(ru.getCondition())) { // 直推复投比例
					rule.setOneRepeatRate(new BigDecimal(ru.getValue()));
				}

				if ("06".equals(ru.getCondition())) { // 间推奖比例（占消费金额的比例）
					rule.setTwoRate(new BigDecimal(ru.getValue()));
				}
				if ("07".equals(ru.getCondition())) { // 用户间推奖比率（占间推奖的比例）
					rule.setTwoUserRate(new BigDecimal(ru.getValue()));
				}
				if ("08".equals(ru.getCondition())) { // 间推粮票比率
					rule.setTwoPointsRate(new BigDecimal(ru.getValue()));
				}
				if ("09".equals(ru.getCondition())) { // 间推手续费比例
					rule.setTwoServiceRate(new BigDecimal(ru.getValue()));
				}
				if ("10".equals(ru.getCondition())) { // 间推复投比例
					rule.setTwoRepeatRate(new BigDecimal(ru.getValue()));
				}

//				if ("11".equals(ru.getCondition())) { // 见点金额
//					rule.setIndirectAmount(new BigDecimal(ru.getValue()));
//				}
				if ("12".equals(ru.getCondition())) { // 用户见点奖比例（占见点金额的比例）
					rule.setIndirectUserRate(new BigDecimal(ru.getValue()));
				}
				if ("13".equals(ru.getCondition())) { // 见点粮票比例
					rule.setIndirectPointsRate(new BigDecimal(ru.getValue()));
				}
				if ("14".equals(ru.getCondition())) { // 见点手续费比例
					rule.setIndirectServiceRate(new BigDecimal(ru.getValue()));
				}
				if ("15".equals(ru.getCondition())) { // 见点复投比例
					rule.setIndirectRepeatRate(new BigDecimal(ru.getValue()));
				}
//				if ("16".equals(ru.getCondition())) { // 见点金额比例
//					rule.setIndirectRate(new BigDecimal(ru.getValue()));
//				}
				if ("17".equals(ru.getCondition())) { // 见点档次
					if(StringUtils.isEmpty(ru.getValue())){
						result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "见点档次规则有误!"));
						return result;
					}
					if(StringUtils.isEmpty(ru.getReserve1())){
						result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "见点上限集合规则有误!"));
						return result;
					}
					if(StringUtils.isEmpty(ru.getReserve2())){
						result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "见点复投断点设置规则有误!"));
						return result;
					}
					if(StringUtils.isEmpty(ru.getReserve3())){
						result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "见点比率设置规则有误!"));
						return result;
					}
					PointRule pr = new PointRule();
					pr.setLeveKey(new BigDecimal(ru.getValue()));
					pr.setRatio(new BigDecimal(ru.getReserve3()).divide(new BigDecimal(100))); //设置比率
					
					String[] liAyy = ru.getReserve1().split(",");
					for(String str : liAyy){
						String[] keyValue = str.split("=");
						if(keyValue.length == 2){
							pr.getRatLimitMap().put(keyValue[0], keyValue[1]); // 设置见点上限集合							
						} else {
							result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "设置见点上限集合失败，见点档次规则有误!"));
							return result;
						}
					}
					pr.setRepPoints(ru.getReserve2().split(",")); //设置隔断点
					rule.getIndirectMap().put(ru.getValue(), pr);
				}
				if ("18".equals(ru.getCondition())) { // 见点将累计界限（百分比）
					if(StringUtils.isEmpty(ru.getValue())){
						result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "见点将累计界限（百分比）规则有误!"));
						return result;
					}
					rule.setIndirectAccLimit(new BigDecimal(ru.getValue()).divide(new BigDecimal(100)));
				}
				
//				if ("30".equals(ru.getCondition())) { // 小公排 规则
//					if(StringUtils.isEmpty(ru.getValue())){
//						result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "公排规则有误!"));
//						return result;
//					}
//					rule.setPubOrder(ru.getValue().split(","));
//				}
				if ("40".equals(ru.getCondition())) { // 复投阈值
					if(StringUtils.isEmpty(ru.getValue())){
						result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "复投阈值规则有误!"));
						return result;
					}
					if(StringUtils.isEmpty(ru.getReserve1())){
						result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "复投阈值对应复投金额有误!"));
						return result;
					}
					rule.setRepeatLimit(new BigDecimal(ru.getValue()));
					rule.setRepeatLimitValue(new BigDecimal(ru.getReserve1()));
				}
				if ("41".equals(ru.getCondition())) { // 复投虚拟商品id
					if(StringUtils.isEmpty(ru.getValue())){
						result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "复投虚拟商品规则有误!"));
						return result;
					}
					rule.setRepeatGoodsId(Integer.valueOf(ru.getValue()));
				}

				if ("50".equals(ru.getCondition())) { // 粮票兑换比例
					rule.setExchangeRate(new BigDecimal(ru.getValue()));
				}

			}
			log.info("【设置活动规则参数】---【校验规则参数】-----");
			if (rule.getOneRate() == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "直推奖比例不能为空!"));
				return result;
			}
			if (rule.getOneUserRate() == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "用户实际直推奖比例不能为空!"));
				return result;
			}
			if (rule.getOnePointsRate() == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "直推粮票比例不能为空!"));
				return result;
			}
			if (rule.getOneServiceRate() == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "直推手续费比例不能为空!"));
				return result;
			}
			if (rule.getOneRepeatRate() == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "直推复投比例不能为空!"));
				return result;
			}

			if (rule.getTwoRate() == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "间推奖比例不能为空!"));
				return result;
			}
			if (rule.getTwoUserRate() == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "用户实际间推奖比例不能为空!"));
				return result;
			}
			if (rule.getTwoPointsRate() == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "间推粮票比例不能为空!"));
				return result;
			}
			if (rule.getTwoServiceRate() == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "间推手续费比例不能为空!"));
				return result;
			}
			if (rule.getTwoRepeatRate() == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "间推复投比例不能为空!"));
				return result;
			}
			
//			if (rule.getIndirectRate() == null) {
//				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "见点奖金额比例不能为空!"));
//				return result;
//			}
//			if (rule.getIndirectAmount() == null) {
//				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "见点奖金额不能为空!"));
//				return result;
//			}
			if (rule.getIndirectUserRate() == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "用户实际见点奖比例不能为空!"));
				return result;
			}
			if (rule.getIndirectPointsRate() == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "见点粮票比例不能为空!"));
				return result;
			}
			if (rule.getIndirectServiceRate() == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "见点手续费比例不能为空!"));
				return result;
			}
			if (rule.getIndirectRepeatRate() == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "见点复投比例不能为空!"));
				return result;
			}

			if (rule.getExchangeRate() == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "粮票兑换比例不能为空!"));
				return result;
			}
			
			// 设置直推奖励
			rule.setOneAmount(
					rule.getOneRate().multiply(price).divide(new BigDecimal(100)).setScale(4, BigDecimal.ROUND_DOWN));
			// 设置用户直推金额
			rule.setOneUserAmount(rule.getOneAmount().multiply(rule.getOneUserRate()).divide(new BigDecimal(100))
					.setScale(4, BigDecimal.ROUND_DOWN));
			// 设置直推粮票
			rule.setOnePoints(rule.getOneAmount().multiply(rule.getOnePointsRate()).multiply(rule.getExchangeRate())
					.divide(new BigDecimal(100)).setScale(4, BigDecimal.ROUND_DOWN));
			// 设置直推手续费
			rule.setOneServiceAmount(rule.getOneAmount().multiply(rule.getOneServiceRate()).divide(new BigDecimal(100))
					.setScale(4, BigDecimal.ROUND_DOWN));
			// 设置直推复投金额
			rule.setOneRepeatAmount(rule.getOneAmount().multiply(rule.getOneRepeatRate()).divide(new BigDecimal(100))
					.setScale(4, BigDecimal.ROUND_DOWN));

			// 设置间推奖励
			rule.setTwoAmount(
					rule.getTwoRate().multiply(price).divide(new BigDecimal(100)).setScale(4, BigDecimal.ROUND_DOWN));
			// 设置用户间推金额
			rule.setTwoUserAmount(rule.getTwoAmount().multiply(rule.getTwoUserRate()).divide(new BigDecimal(100))
					.setScale(4, BigDecimal.ROUND_DOWN));
			// 设置间推粮票
			rule.setTwoPoints(rule.getTwoAmount().multiply(rule.getTwoPointsRate()).multiply(rule.getExchangeRate())
					.divide(new BigDecimal(100)).setScale(4, BigDecimal.ROUND_DOWN));
			// 设置间推手续费
			rule.setTwoServiceAmount(rule.getTwoAmount().multiply(rule.getTwoServiceRate()).divide(new BigDecimal(100))
					.setScale(4, BigDecimal.ROUND_DOWN));
			// 设置间推复投金额
			rule.setTwoRepeatAmount(rule.getTwoAmount().multiply(rule.getTwoRepeatRate()).divide(new BigDecimal(100))
					.setScale(4, BigDecimal.ROUND_DOWN));

			result.put("rule", rule);
			result.put("result",
					(ResultInfo) ResultUtil.initResult(ResultInfo.SUCCESS, "setRules_success", "设置规则参数成功"));
			log.info("【设置活动规则参数】---【成功】-----");
		} catch (Exception e) {
			log.error("设置活动规则参数】---【异常】-----", e);
			result.put("result",
					(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "setRules_exception", "设置规则参数异常！", "", "01"));
		}
		log.info("【设置活动规则参数】---【结束】-----");
		return result;
	}

	/**
	 * 分润业务处理
	 *
	 * @param ruleList
	 *            处理规则
	 * @param userList
	 *            用户上级列表
	 * @param userId
	 *            消费用户id
	 * @param billId
	 *            消费账单
	 * @param activityId
	 *            活动id
	 *  @param goodsId
	 *            活动商品id
	 * @return Map<String, Object>
	 */
	public Map<String, Object> insertRebate(List<UserInfo> userList, Rule rule, BigDecimal price, 
			Integer userId, Long billId, Integer activityId, Integer goodsId) {
		Map<String, Object> result = new HashMap<String, Object>();
		log.info("【生成分润业务数据】---【开始】---");
		try {
			log.info("【多级分润处理】---【开始每级处理】-----");
			// 构建保存结果
			List<TransactionFlowPo> tfList = new ArrayList<TransactionFlowPo>();// 构建分润交易订单
			String type = "01";
			// 处理直推间推
			for (int i = 0; i < userList.size(); i++) {
				UserInfo ui = userList.get(i);
				if (i == 0) {
					type = "01";
				} else {
					type = "02";
				}
				//排除禁用用户和不在权益周期用户
				if("01".equals(ui.getState()) && "01".equals(ui.getBuyState())) {
					String level = (i < 9) ? "0" + (i + 1) : "" + (i + 1);
					result = setTransactionFlow(tfList, ui, rule, level, billId, type);
					ResultInfo ri = (ResultInfo) result.get("result");
					if (ResultInfo.ERROR.equals(ri.getState())) {
						String errorCode = "01".equals(type) ? "tranflow_help_error" : "tranflow_error";
						result.put("result",
								(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, errorCode, ri.getMessage(), "", "01"));
						return result;
					}
				}
				
			}
			// 处理见点 
			log.info("【生成分润业务数据】---【获取用户小公排多级上级开始】-----");
			Map<String, Object> mulityMap = activityService.getIndirectParents(activityId, userId, 50);
			if (mulityMap == null) {
				log.error("【生成分润业务数据】---【获取用户多级上级】---【结果为null】-----");
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "userPubPanent_error", "获取小公排用户多级上级异常!", "", "01"));
				return result;
			}
			ResultInfo mulityRi = (ResultInfo) mulityMap.get("result");
			if (ResultInfo.ERROR.equals(mulityRi.getState())) {
				log.error("【多级分润处理】---【获取用户多级上级】---【异常】-----code={},msg={}", mulityRi.getCode(), mulityRi.getMessage());
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "userPubPanent_error1", "获取小公排用户多级上级异常!", "", "01"));
				return result;
			}
			log.info("【多级分润处理】---【获取用户多级上级】---【结果为】-----{}", mulityMap.toString());
			List<UserInfo> userPubList = (List<UserInfo>) mulityMap.get("listUser");
			BigDecimal addLimit = BigDecimal.ZERO; //执行返利百分比累计
			for(int m = 0; m < userPubList.size(); m++) {
				UserInfo up = userPubList.get(m);
				if(!"01".equals(up.getState())) {
					log.info("【多级分润处理】---【当前用户非正常状态，执行跳过】-----userId={},state={}", up.getId(), up.getState());
					continue;
				}
				
				PointRule curPointRule = null; //该用户见点档次
				BigDecimal pointLimit = BigDecimal.ZERO ; // 该用户见点上限
				
				// 获取用户活动累计信息
				log.info("【多级分润处理】---【获取用户活动累计信息】---userId={},activityId={}", up.getId(), activityId);
				ActivityUserInfo acUser = activityRepeatDetailMapper.getActivityUserInfo(activityId, up.getId());
				if (acUser == null) {
					log.info("【多级分润处理】---【获取用户多级上级】---【获取用户活动累计信息为null,跳过】-----");
					continue;
				}
				List<String> dList = new ArrayList<>(rule.getIndirectMap().keySet()); //构建档次集合
				Collections.sort(dList); // 默认升序
				
				BigDecimal addConsume = acUser.getAddConsume() == null ? BigDecimal.ZERO : acUser.getAddConsume();
				BigDecimal addRepeat = acUser.getAddRepeat() == null ? BigDecimal.ZERO : acUser.getAddRepeat();
				BigDecimal total = addConsume.add(addRepeat);
				String curPointRuleKey = getMidNumber(total, dList); //获取档次区间
				log.info("【多级分润处理】---【获取用档次key】---curPointRuleKey={}", curPointRuleKey);
				if (StringUtils.isEmpty(curPointRuleKey)) {
					log.info("【多级分润处理】---【获取用档次key为空，执行跳过】---");
					continue;
				}
				curPointRule = rule.getIndirectMap().get(curPointRuleKey);
				if (curPointRule == null) {
					log.info("【多级分润处理】---【获取用户档次】---【结果为null,跳过】-----userid={},addConsume={},addRepeat={}", up.getId(),acUser.getAddConsume(),acUser.getAddRepeat());
					continue;
				} else {
					log.info("【多级分润处理】---【获取用户档次】---Ratio={}", curPointRule.getRatio());
					//获取用户见点上限，根据用户直推下级人数已经下级的复投次数
					Map<String, Object> acMap = new HashMap<>();
					acMap.put("type", "00");
					acMap.put("userId", up.getId());
					acMap.put("activityId", activityId);
					List<ActivityUserInfo> acList = activityRepeatDetailMapper.getActivityUserAccInfo(acMap);
					String curKey = getRatLimitKey(acList, curPointRule);
					log.info("【多级分润处理】---【获取用户档次见点上限key】---curKey={}", curKey);
					if(StringUtils.isEmpty(curKey)) {
						result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "curPointRuleKey_error", "获取用户见点上限key异常!", "", "01"));
						return result;
					}
					String pointLimitValue = curPointRule.getRatLimitMap().get(curKey); // 设置该用户见点上限
					log.info("【多级分润处理】---【获取用户档次见点上限值为】---pointLimitValue={}", pointLimitValue);
					if(StringUtils.isEmpty(pointLimitValue)) {
						result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "curPointRule_error", "获取用户见点上限异常!", "", "01"));
						return result;
					}
					pointLimit = new BigDecimal(pointLimitValue);
					// 设置当前用户见点比例
					rule.setIndirectRate(curPointRule.getRatio());
					// 设置见点奖励
					rule.setIndirectAmount(rule.getIndirectRate().multiply(price).setScale(4, BigDecimal.ROUND_DOWN));
					// 设置用户见点金额
					rule.setIndirectUserAmount(rule.getIndirectAmount().multiply(rule.getIndirectUserRate())
							.divide(new BigDecimal(100)).setScale(4, BigDecimal.ROUND_DOWN));
					// 设置见点粮票
					rule.setIndirectPoints(rule.getIndirectAmount().multiply(rule.getIndirectPointsRate()).divide(new BigDecimal(100))
							.multiply(rule.getExchangeRate()).setScale(4, BigDecimal.ROUND_DOWN));
					// 设置见点手续费
					rule.setIndirectServiceAmount(rule.getIndirectAmount().multiply(rule.getIndirectServiceRate())
							.divide(new BigDecimal(100)).setScale(4, BigDecimal.ROUND_DOWN));
					// 设置见点复投金额
					rule.setIndirectRepeatAmount(rule.getIndirectAmount().multiply(rule.getIndirectRepeatRate())
							.divide(new BigDecimal(100)).setScale(4, BigDecimal.ROUND_DOWN));
					log.info("【多级分润处理】---【获取用户档次见点拆分信息】---当前用户见点比例{},见点奖励{}", rule.getIndirectRate(), rule.getIndirectAmount());
					log.info("【多级分润处理】---【获取用户档次见点拆分信息】---当前用户见点金额{},见点粮票{}", rule.getIndirectUserAmount(), rule.getIndirectPoints());
					log.info("【多级分润处理】---【获取用户档次见点拆分信息】---当前用户见点手续费{},见点复投金额{}", rule.getIndirectServiceAmount(), rule.getIndirectRepeatAmount());
				}
				//当前比率加累计比率 小于上限
				log.info("【多级分润处理】---【获取用户档次见点上限累计达到阈值】---limitValue={},addValue={}", rule.getIndirectAccLimit(), addLimit.add(rule.getIndirectRate()));
				if((addLimit.add(rule.getIndirectRate())).compareTo(rule.getIndirectAccLimit()) > 0 ) {
					break;
				}
				if((acUser.getAddRebateDream().add(rule.getIndirectUserAmount())).compareTo(pointLimit) <= 0){
					String level = (m < 9) ? "0" + (m + 1) : "" + (m + 1);
					result = setTransactionFlow(tfList, up, rule, level, billId, "");
					ResultInfo ri = (ResultInfo) result.get("result");
					if (ResultInfo.ERROR.equals(ri.getState())) {
						result.put("result",
								(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "tranflow_view_error", ri.getMessage(), "", "01"));
						return result;
					}
					addLimit = addLimit.add(rule.getIndirectRate());
				}
				
			}
			
			if (tfList.size() <= 0) {
				log.info("【【多级分润处理】---】---【不存在保存账单】-----");
				result.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "tf_success", "无账单不触发分润业务操作成功"));
				return result;
			}
			// 保存交易订单
			result = saveTransactionFlow(tfList);
			ResultInfo tranResult = (ResultInfo) result.get("result");
			if (ResultInfo.ERROR.equals(tranResult.getState())) {
				result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "tranflowsave_error",
						"生成交易订单异常！", "", "01"));
				return result;
			}

			// 产生分润记录
			result = insertCommission(tfList, userId, activityId, rule);
			ResultInfo commResult = (ResultInfo) result.get("result");
			if (ResultInfo.ERROR.equals(commResult.getState())) {
				result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, commResult.getCode(),
						"生成分润记录异常！", "", "01"));
				return result;
			}

			// 产生分润用户的余额明细 并且 修改分润的用户账户余额 粮票修改 产生粮票明细
			result = updateAccountAndAddtBalance(tfList);
			ResultInfo baResult = (ResultInfo) result.get("result");
			if (ResultInfo.ERROR.equals(baResult.getState())) {
				result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, baResult.getCode(),
						"生成账户余额明细异常！", "", "01"));
				return result;
			}
			// 复投  生成复投明细，累计复投资金满后 生成扣除轨迹，并触发虚拟多级分润
			result = insertRepeat(tfList, userId, rule, activityId, goodsId);
			ResultInfo reResult = (ResultInfo) result.get("result");
			if (ResultInfo.ERROR.equals(reResult.getState())) {
				result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, reResult.getCode(),
						"复投业务处理异常！", "", "01"));
				return result;
			}
			// 发送站内信
			((MultilevelRebateServiceImpl)AopContext.currentProxy()).sendMsgByTf(tfList);
			// push消息
			((MultilevelRebateServiceImpl)AopContext.currentProxy()).pushMsgByTf(tfList);

			result.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "insertFirst_success", "分润业务操作成功"));
			log.info("【生成分润业务数据】---【结束】-----");
			return result;
		} catch (Exception e) {
			rule.getRepeatInfos().clear();
			log.error("【生成分润业务数据】---【异常】-----{}", e);
			result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "insertFirst_exception",
					"生成分润业务数据异常！", "", "01"));
			return result;
		}

	}
	/**
	 * 返回当前档次规则的见点上限key
	 * @param list 用户复投集合
	 * @param curPointRule 当前规则
	 * @return String 见点上限key
	 */
	public String getRatLimitKey(List<ActivityUserInfo> list, PointRule curPointRule) {
		StringBuffer result = new StringBuffer();
		List<String> poins = Arrays.asList(curPointRule.getRepPoints());
		log.info("【当前用户见点规则】---【当前规则断点集合】---{}", poins.toString());
		Collections.sort(poins); // 默认升序
		if(list == null || list.size() == 0) {
			result.append("N0N0");
			log.info("【当前用户见点规则】---【获取用户见点上限】---key=N0N0");
			
		} else if(list.size() == 1) {
			ActivityUserInfo af = list.get(0);
			log.info("【当前用户见点规则】---【获取用户见点上限】---repeatNumber={}", af.getRepeatNumber());
			String res = getMidNumber(new BigDecimal(af.getRepeatNumber()), poins);
			log.info("【当前用户见点规则】---【获取用户见点上限】---【区间值】---{}", res);
			result.append("N0");
			if(StringUtils.isEmpty(res)) {
				result.append("N1");
			} else {
				result.append("P" + res.trim());
			}
		} else {
			List<String> st = new ArrayList<>();
			for (int i = 0; i < list.size(); i++) {
				if(i == 2) {
					break;
				}
				StringBuffer tmp = new StringBuffer();
				ActivityUserInfo a1 = list.get(i);
				log.info("【当前用户见点规则】---【获取用户见点上限】---【first】---repeatNumber={}", a1.getRepeatNumber());
				String res = getMidNumber(new BigDecimal(a1.getRepeatNumber()), poins);
				log.info("【当前用户见点规则】---【获取用户见点上限】---【区间值】---{}", res);
				if(StringUtils.isEmpty(res)) {
					tmp.append("N1");
				} else {
					tmp.append("P" + res.trim());
				}
				st.add(tmp.toString());
			}
			Collections.sort(st);
			result.append(st.get(0)).append(st.get(1));
		}
		log.info("【当前用户见点规则】---【key】---{}", result.toString());
		return result.toString();
	}
	
	/**
	 * 返回key所在区间的起始值
	 * @param key 值
	 * @param list 集合
	 * @return 区间起始值
	 */
	public String getMidNumber(BigDecimal key,List<String> list){
		String result = null;
		log.info("【返回key所在区间的起始值】---【开始】---key={},list={}-----", key, list.toString());
		if(list.size() == 1) {
			if(key.compareTo(new BigDecimal(list.get(0))) < 0) {
				return result;
			}else {
				result = list.get(0);
				return result;
			}
		}
		for(int j=0; j < list.size() - 1; j++) {
			if(key.compareTo(new BigDecimal(list.get(j))) < 0) {
				break;
			}
			if(key.compareTo(new BigDecimal(list.get(list.size() - 1))) >= 0) {
				result = list.get(list.size() - 1);
				break;
			}
			if(key.compareTo(new BigDecimal(list.get(j))) >= 0 && key.compareTo(new BigDecimal(list.get(j+1))) < 0) {
				result = list.get(j);
				break;
			}
		}
		log.info("【返回key所在区间的起始值】---【result】---{}", result);
		return result;
	}
	/**
	 * 判断用户是否在集合中
	 * 
	 * @param usr
	 *            用户上级集合
	 * @param userId
	 *            用户标识
	 * @return boolean
	 */
	public boolean checkUserInfo(List<ActivityUserRelation> usr, Integer userId) {
		log.info("【用户是否参与多级分润】---【开始】-----userId={}", userId);
		boolean flag = false;
		try {
			for (ActivityUserRelation u : usr) {
				if (userId == u.getUserId()) {
					flag = true;
				}
			}
			log.info("【用户是否参与多级分润】---【成功】-----");
		} catch (Exception e) {
			log.error("用户是否参与多级分润】---【异常】-----", e);
		}
		log.info("【用户是否参与多级分润】---【结束】-----flag={}", flag);
		return flag;
	}

	/**
	 * 保存交易订单
	 * 
	 * @param tflist
	 *            交易订单
	 * @param user
	 *            当前用户
	 * @param index
	 *            级别
	 * @param billId
	 *            父级账单ID
	 * @param remark
	 *            备注
	 * @param type
	 *            类型
	 * @return Map<String, Object>
	 */
	public Map<String, Object> setTransactionFlow(List<TransactionFlowPo> tflist, UserInfo user, Rule rule, String level,
			Long billId, String type) {
		Map<String, Object> result = new HashMap<String, Object>();
		log.info("【构建分润交易订单】-第{}级--【开始】", level);
		try {
			log.info("【构建分润交易订单】---【当前用户id:{}】", user.getId());
			BigDecimal userAmount = BigDecimal.ZERO;
			BigDecimal serviceAmount = BigDecimal.ZERO;
			BigDecimal repeatAmount = BigDecimal.ZERO;
			BigDecimal points = BigDecimal.ZERO;
			BigDecimal rebate = BigDecimal.ZERO;
			String remark = "";
			String rebateType = "";
			String flagType = "";
			if ("01".equals(type)) {
				userAmount = rule.getOneUserAmount();
				serviceAmount = rule.getOneServiceAmount();
				repeatAmount = rule.getOneRepeatAmount();
				points = rule.getOnePoints();
				rebate = rule.getOneUserRate();
				rebateType = "00";
				remark = "直推助农奖";
				flagType = "01";
			} else if ("02".equals(type)) {
				userAmount = rule.getTwoUserAmount();
				serviceAmount = rule.getTwoServiceAmount();
				repeatAmount = rule.getTwoRepeatAmount();
				points = rule.getTwoPoints();
				rebate = rule.getTwoUserRate();
				rebateType = "00";
				remark = "间推助农奖";
				flagType = "02";
			} else {
				userAmount = rule.getIndirectUserAmount();
				serviceAmount = rule.getIndirectServiceAmount();
				repeatAmount = rule.getIndirectRepeatAmount();
				points = rule.getIndirectPoints();
				rebate = rule.getIndirectUserRate();
				rebateType = "00";
				remark = "圆梦奖";
				flagType = "03";
			}
			// 构建分润交易订单
			TransactionFlowPo tFlow = new TransactionFlowPo();
			tFlow.setUserId(user.getId()); // 当前用户id
			tFlow.setParentId(billId); // 消费者账单id
			tFlow.setTotalPrice(userAmount); // 设置金额
			tFlow.setPayPrice(userAmount); // 设置金额
			tFlow.setPriceState("01"); // 进
			tFlow.setType(BillConstant.Type.rebeate.getValue()); // 分润
			if("01".equals(flagType)) {
				tFlow.setSubType(BillConstant.SubType.rebate_help_farm_one.getValue());
			} else if("02".equals(flagType)) {
				tFlow.setSubType(BillConstant.SubType.rebate_help_farm_two.getValue());
			}else {
				tFlow.setSubType(BillConstant.SubType.rebate_dream_farm.getValue());
			}			
			tFlow.setRemark(remark);
			tFlow.setState("01"); // 已支付
			tFlow.setCreateTime(DateUtil.getTime());
			tFlow.setFinishTime(DateUtil.getTime());
			tFlow.setVersion(0);
			tFlow.getCd().setLevel(level);
			tFlow.getCd().setFriendId(user.getChildUserId());
			tFlow.getCd().setRebate(rebate);
			tFlow.getCd().setRebateType(rebateType);
			tFlow.setIsShow("00");
			tFlow.setTicket(points);
			tflist.add(tFlow);
			// 手续费
			TransactionFlowPo sFlow = new TransactionFlowPo();
			sFlow.setUserId(user.getId()); // 当前用户id
			sFlow.setParentId(billId); // 消费者账单id
			sFlow.setTotalPrice(serviceAmount); // 设置金额
			sFlow.setPayPrice(serviceAmount); // 设置金额
			sFlow.setPriceState("01"); // 进
			sFlow.setType(BillConstant.Type.other.getValue()); // 手续费
			sFlow.setSubType(BillConstant.SubType.other_process.getValue());
			sFlow.setRemark(remark + "手续费");
			sFlow.setState("01"); // 已支付
			sFlow.setCreateTime(DateUtil.getTime());
			sFlow.setFinishTime(DateUtil.getTime());
			sFlow.setVersion(0);
			sFlow.setIsShow("01");
			tflist.add(sFlow);
			// 复投
			TransactionFlowPo rFlow = new TransactionFlowPo();
			rFlow.setUserId(user.getId()); // 当前用户id
			rFlow.setParentId(billId); // 消费者账单id
			rFlow.setTotalPrice(repeatAmount); // 设置金额
			rFlow.setPayPrice(repeatAmount); // 设置金额
			rFlow.setPriceState("01"); // 进
			rFlow.setType(BillConstant.Type.other.getValue()); // 复投
			rFlow.setSubType(BillConstant.SubType.other_repeat.getValue());
			rFlow.setRemark(remark + "复投金额");
			rFlow.setState("01"); // 已支付
			rFlow.setCreateTime(DateUtil.getTime());
			rFlow.setFinishTime(DateUtil.getTime());
			rFlow.setVersion(0);
			rFlow.setIsShow("01");
			tflist.add(rFlow);
			
			log.info("【构建分润交易订单】-第{}级--【结束】", level);
			result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.SUCCESS, "tranflow_success",
					"构建第" + level + "级分润交易订单异常！"));
			return result;
		} catch (Exception e) {
			log.error("【构建分润交易订单】-第{}级---【异常---{}】", level, e);
			result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "tranflow_exception",
					"【构建第" + level + "级分润交易订单异常！】", "", "01"));
			return result;
		}
	}

	/**
	 * 保存交易订单
	 *
	 * @param tflist
	 *            交易订单集合
	 * @param user
	 *            用户
	 * @param money
	 *            支付金额
	 * @param state
	 *            01 进 02出
	 * @return 保存结果
	 */
	public Map<String, Object> saveTransactionFlow(List<TransactionFlowPo> tflist) {
		Map<String, Object> result = new HashMap<String, Object>();
		log.info("【构建分润交易订单】---【开始】---");
		try {
			if (tflist.size() <= 0) {
				log.info("【构建分润交易订单】---【不存在保存账单】-----");
				result.put("result",
						(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "tranflow_error", "生成分润交易订单异常！"));
				return result;
			}
			log.info("【构建分润交易订单】---【saveparams】-----" + tflist.toString());
			// 保存分润交易订单
			transactionFlowPoMapper.insertTransactionFlows(tflist);
			for (TransactionFlowPo t : tflist) {
				// 构建交易订单编码
				t.setCode(CustomUtil.orderCode(3, t.getId(), t.getUserId()));
			}
			log.info("【构建分润交易订单】---【updateparams】-----" + tflist.toString());
			for (TransactionFlowPo tfp : tflist) {
				int upRec = transactionFlowPoMapper.updateCode(tfp);
				if (upRec != 1) {
					log.info("【构建分润交易订单】---【插入交易订单编码失败！】----影响记录数：=" + upRec);
					result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "tranflow_error",
							"生成分润交易订单异常！", "", "01"));
					return result;
				}
			}
			log.info("【构建分润交易订单】---【结束】-----");
			result.put("result",
					(ResultInfo) ResultUtil.initResult(ResultInfo.SUCCESS, "tranflow_success", "交易订单生成成功"));
			return result;
		} catch (Exception e) {
			log.error("【构建分润交易订单】---【生成分润交易订单异常！】-----{}", e);
			result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "tranflow_exception",
					"生成分润交易订单异常！", "", "01"));
			return result;
		}
	}

	/**
	 * 生成分润记录
	 *
	 * @param tflist
	 *            交易账单记录
	 * @param userId
	 *            消费用户id
	 * @param activityId
	 *            活动id
	 * @param rule
	 *            活动规则
	 * @return 保存结果
	 */
	public Map<String, Object> insertCommission(List<TransactionFlowPo> tflist, Integer userId, Integer activityId, Rule rule) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			log.info("【佣金分润记录】---【开始】---");
			List<CommissionDetail> commlist = new ArrayList<CommissionDetail>(); // 构造佣金分润记录
			for (TransactionFlowPo t : tflist) {
				if ("02".equals(t.getType())) {
					log.info("【佣金分润记录】---【佣金分润记录账单信息】---{}", t.toString());
					// 构建分润记录
					CommissionDetail commDetail = t.getCd();
					commDetail.setUserId(t.getUserId()); // 用户id
					commDetail.setMoney(t.getPayPrice()); // 分润金额
					commDetail.setRemark(t.getRemark());//描述
					commDetail.setTransactionId(t.getId()); // 交易订单id
					commDetail.setCreateTime(DateUtil.getTime());//创建时间
					commDetail.setConsumerId(userId); // 消费者id
					commDetail.setPriceState("01");//金额状态
					commDetail.setType("01");//多级分润
					commlist.add(commDetail);
					
					// 用户分润累计
					ActivityUserInfo acUser = new ActivityUserInfo();
					acUser.setActivityId(activityId);
					acUser.setUserId(t.getUserId());
					if(BillConstant.SubType.rebate_help_farm_one.getValue().equals(t.getSubType()) || BillConstant.SubType.rebate_help_farm_two.getValue().equals(t.getSubType())) {
						acUser.setAddRebate(t.getPayPrice());
						acUser.setType("3");
					}
					if(BillConstant.SubType.rebate_dream_farm.getValue().equals(t.getSubType())) {
						acUser.setAddRebateDream(t.getPayPrice());
						acUser.setType("5");
					}
					
					log.info("【佣金分润记录】---【用户分润累计余额-更新】-----{}", acUser.toString());
					// 修改用户分润累计
					int rec = activityRepeatDetailMapper.updateActivityUserInfo(acUser);					
					if (rec != 1) {
						log.error("【佣金分润记录】---【用户分润累计失败！】----影响记录数：=" + rec);
						result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "acRebate_update_error",
								"用户分润累计异常！", "", "01"));
						return result;
					}
					rule.getUpSet().add(t.getUserId()); //构建公排累计收益
				}

			}
			if (commlist.size() <= 0) {
				log.error("【佣金分润记录】---【构建分润记录异常】-----");
				result.put("result",
						(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "commiss_error", "分润记录异常！", "", "01"));
				return result;
			}
			log.info("【佣金分润记录】---【saveparams】-----" + commlist.toString());
			// 保存分润记录
			commissionDetailMapper.insertCommissionDetails(commlist);
			result.put("result",
					(ResultInfo) ResultUtil.initResult(ResultInfo.SUCCESS, "commiss_success", "生成分润记录成功！"));
			log.info("【佣金分润记录】---【结束】-----");
			return result;
		} catch (Exception e) {
			rule.getUpSet().clear();
			log.error("【佣金分润记录】---【生成分润记录异常！】-----{}", e);
			result.put("result",
					(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "commiss_exception", "生成分润记录异常！", "", "01"));
			return result;
		}
	}
	
	/**
	 * 处理复投业务
	 *
	 * @param tflist
	 *            交易账单记录
	 * @param userId
	 *            消费用户id
	 * @param rule
	 *            规则
	 * @param activityId
	 *            活动id
	 * @param goodsId
	 *            活动商品id
	 * @return 保存结果
	 */
	public Map<String, Object> insertRepeat(List<TransactionFlowPo> tflist, Integer userId, Rule rule, Integer activityId, Integer goodsId) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			log.info("【处理复投业务】---【开始】---");
			List<ActivityRepeatDetail> reList = new ArrayList<ActivityRepeatDetail>(); // 构造佣金分润记录
			for (TransactionFlowPo t : tflist) {
				if ("05".equals(t.getType()) && BillConstant.SubType.other_repeat.equals(t.getSubType())) { //复投
					log.info("【处理复投业务】---【复投业务账单信息】---{}", t.toString());
					// 用户复投基金累计
					ActivityUserInfo acUser = new ActivityUserInfo();
					acUser.setActivityId(activityId);
					acUser.setUserId(t.getUserId());
					acUser.setCurAddRepeat(t.getPayPrice());
					acUser.setAddRepeat(t.getPayPrice());
					acUser.setType("4");
					
					log.info("【处理复投业务】---【用户复投累计余额-更新】-----{}", acUser.toString());
					// 修改用户复投基金累计
					int rec = activityRepeatDetailMapper.updateActivityUserInfo(acUser);					
					if (rec != 1) {
						log.error("【处理复投业务】---【更新用户复投基金失败！】----影响记录数：=" + rec);
						result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "actRepeat_update_error",
								"用户复投基金异常！", "", "01"));
						return result;
					}
					//复投明细
					ActivityRepeatDetail re = new ActivityRepeatDetail();
					re.setActivityId(activityId); 
					re.setCreateTime(DateUtil.getTime());//创建时间
					re.setCurRepeat(acUser.getCurAddRepeat().subtract(t.getPayPrice()));
					re.setIncomeState("01"); // 收益状态 01 增 00 减
					re.setRemark(t.getRemark());
					re.setRepeat(t.getPayPrice());
					re.setTransactionId(t.getId());
					re.setType("01"); // 01 活动产生  02 消费
					re.setUpdateTime(DateUtil.getTime());
					re.setUserId(t.getUserId());
					reList.add(re);
					
					// 累计比余额大 则触发再次复投
					if(acUser.getCurAddRepeat().compareTo(rule.getRepeatLimit()) > 0) {
						// 新增扣减明细，修改余额
						// 用户复投基金累计
						ActivityUserInfo acu = new ActivityUserInfo();
						acu.setActivityId(activityId);
						acu.setUserId(t.getUserId());
						acu.setCurAddRepeat(BigDecimal.ZERO.subtract(rule.getRepeatLimit()));
						acu.setAddRepeat(BigDecimal.ZERO);
						acu.setType("4");

						log.info("【处理复投业务】---【触发用户再次复投累计余额-更新】-----{}", acu.toString());
						// 修改用户复投基金累计
						int i = activityRepeatDetailMapper.updateActivityUserInfo(acu);					
						if (i != 1) {
							log.error("【处理复投业务】---【触发用户再次复投累计余额失败！】----影响记录数：=" + i);
							result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "actRepeat_update_error2",
									"触发用户再次复投基金异常！", "", "01"));
							return result;
						}
						//复投明细
						ActivityRepeatDetail rr = new ActivityRepeatDetail();
						rr.setActivityId(activityId); 
						rr.setCreateTime(DateUtil.getTime());//创建时间
						rr.setCurRepeat(acUser.getCurAddRepeat());
						rr.setIncomeState("00"); // 收益状态 01 增 00 减
						rr.setRemark("触发复投扣减");
						rr.setRepeat(rule.getRepeatLimit());
						rr.setTransactionId(t.getId());
						rr.setType("02"); // 01 活动产生  02 消费
						rr.setUpdateTime(DateUtil.getTime());
						rr.setUserId(t.getUserId());
						reList.add(rr);
						
						// 构建再次复投调用信息
						RepeatInfo reInfo = new RepeatInfo();
						reInfo.setActivityId(activityId);
						reInfo.setBillId(t.getId());
						reInfo.setBuyNum(1);
						reInfo.setGoodsId(rule.getRepeatGoodsId());
						reInfo.setPrice(rule.getRepeatLimitValue());
						reInfo.setUserId(t.getUserId());
						rule.getRepeatInfos().add(reInfo);
						
						//插入产生的兑换券
						ActivityVoucher avm = new ActivityVoucher();
						avm.setCreateTime(DateUtil.getTime());
						avm.setUpdateTime(DateUtil.getTime());
						avm.setDescInfo("可在兑换中心兑换商品");
						avm.setEndUseTime(DateUtil.getTimeByInc(5));
						avm.setMoney(BigDecimal.ONE);
						avm.setState("00");
						avm.setType("01");
						avm.setUserId(t.getUserId());
						
						int nu = activityVoucherMapper.insert(avm);
						if (nu != 1) {
							log.error("【处理复投业务】---【触发用户再次复投】---【产生兑换券】----影响记录数：=" + i);
							result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "actRepeat_insert_error3",
									"触发用户再次复投,产生兑换券异常！", "", "01"));
							return result;
						}
					}
					
				}

			}
			if (reList.size() <= 0) {
				log.error("【处理复投业务】---【构建复投记录异常】-----");
				throw new Exception("无复投数据");
			}
			log.info("【处理复投业务】---【saveparams】-----{}", reList.toString());
			// 保存复投明细记录
			activityRepeatDetailMapper.insertRepeatDetail(reList);
			result.put("result",
					(ResultInfo) ResultUtil.initResult(ResultInfo.SUCCESS, "repeat_save_success", "生成复投明细记录成功！"));
			log.info("【处理复投业务】---【结束】-----");
			return result;
		} catch (Exception e) {
			rule.getRepeatInfos().clear();
			log.error("【处理复投业务】---【异常！】-----{}", e);
			result.put("result",
					(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "repeat_exception", "生成复投明细记录异常！", "", "01"));
			return result;
		}
	}

	/**
	 * 修改账户余额以及新增余额和粮票明细
	 * 
	 * @param balancelist
	 *            构建分润余额明细
	 * @param uList
	 *            构建修改用户余额
	 * @param tflist
	 *            交易账单记录
	 * @return 保存结果
	 */
	public Map<String, Object> updateAccountAndAddtBalance(List<TransactionFlowPo> tflist) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			log.info("【修改账户余额以及新增余额明细】---【开始】-----");
			List<BalanceDetail> balancelist = new ArrayList<BalanceDetail>(); // 构建分润余额明细
			List<TicketDetail> tlist = new ArrayList<TicketDetail>(); // 粮票明细

			for (TransactionFlowPo t : tflist) {
				if ("02".equals(t.getType())) {
					// 获取用户账户余额
					UserAccount userAcc = userAccountMapper.selectByUserId(t.getUserId());
					if (userAcc == null) {
						log.error("【修改账户余额以及新增余额明细】---【构建余额明细】---【获取用户余额异常】------");
						result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "accAalance_error",
								"获取用户余额异常！", "", "01"));
						return result;
					}
					
					// 用户账单余额
					UserAccount uAccount = new UserAccount();
					uAccount.setUserId(t.getUserId()); // 变更id
					uAccount.setBalance(t.getPayPrice()); // 本次变动余额
					uAccount.setVersion(userAcc.getVersion()); // 设置当前版矢量
					uAccount.setTicket(t.getTicket()); // 粮票
					log.info("【修改账户余额以及新增余额明细】---【用户账户余额-更新前】-----" + uAccount.toString());
					// 修改用户账户余额
					int rec = userAccountMapper.updateAcpByUserId(uAccount);
					
					if (rec != 1) {
						log.error("【修改账户余额以及新增余额明细】---【更新用户账户余额失败！】----影响记录数：=" + rec);
						log.error("【修改账户余额以及新增余额明细】---【更新用户账户参数】----[" + uAccount.toString() + "]");
						result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "accAalance_error",
								"更新用户账户余额异常！", "", "01"));
						return result;
					}
					log.info("【修改账户余额以及新增余额明细】---【用户账户余额-更新后】-----" + uAccount.toString());
					
					log.info("【修改账户余额以及新增余额明细】---【构建余额明细】---【获取用户余额信息】------" + userAcc.toString());
					// 余额明细
					BalanceDetail balance = new BalanceDetail();
					balance.setUserId(t.getUserId()); // 用户id
					balance.setMoney(t.getPayPrice()); // 金额
					balance.setIncomeState("01"); // 收益状态 01 增 00 减
					balance.setTransactionId(t.getId());
					balance.setType("03"); // 返销
					balance.setRemark(t.getRemark());
					balance.setCreateTime(DateUtil.getTime());
					balance.setCurBalance(uAccount.getBalance().subtract(t.getPayPrice())); // 设置用户当前余额					
					balancelist.add(balance);
					
					//构建粮票明细
					TicketDetail td = new TicketDetail();
					td.setUserId(t.getUserId()); // 用户id
					td.setTicket(t.getTicket()); // 粮票
					if (uAccount.getTicket() == null) {
						td.setCurTicket(BigDecimal.ZERO);
					} else {
						td.setCurTicket(uAccount.getTicket().subtract(t.getTicket()));
					}
					td.setIncomeState("01");
					td.setType("01");
					td.setRemark(t.getRemark());
					td.setCreateTime(DateUtil.getTime());
					td.setUpdateTime(DateUtil.getTime());
					td.setTransactionId(t.getId());
					tlist.add(td);					
				}
			}

			if (balancelist.size() <= 0) {
				log.error("【修改账户余额以及新增余额明细】---【构建分润余额明细异常】-----" + balancelist.toString());
				result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "accAalance_error",
						"构建分润余额明细异常！", "", "01"));
				return result;
			}
			if (tlist.size() <= 0) {
				log.error("【修改账户余额以及新增余额粮票明细】---【用户账户粮票修改构建参数异常】----");
				result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "accAalance_error4",
						"更新用户账户粮票入参异常！", "", "01"));
				return result;
			}
			log.info("【修改账户余额以及新增余额明细】---【saveparams】-----" + balancelist.toString());
			// 保存余额明细
			balanceDetailMapper.insertBalanceDetails(balancelist);
			// 保存粮票明细
			ticketDetailMapper.insertTicketDetails(tlist);
			result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.SUCCESS, "accAalance_success", "成功！"));
			log.info("【修改账户余额以及新增余额明细】---【结束】-----");
			return result;
		} catch (Exception e) {
			log.error("【修改账户余额以及新增余额明细】---【异常！】-----{}", e);
			result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "accAalance_exception",
					"修改账户余额以及新增余额明细异常！", "", "01"));
			return result;
		}
	}
	
	/**
	 * 发送分润消息
	 *
	 * @param msglist
	 *            消息集合
	 */
	public void sendMsg(List<SysMessage> msglist) {
		log.info("【发送分润消息】---【开始】-----");
		try {
			if (msglist.size() <= 0) {
				log.error("【发送分润消息】---【构建参数异常】----");
			}
			// 根据交易订单构建 发送消息体
			for (SysMessage msg : msglist) {
				try {
					log.info("【发送分润消息】---【消息】-----" + msg.toString());
					sysMessageService.insert(msg);
				} catch (Exception e) {
					log.error("【发送分润消息】---【异常】-----{}", e);
					continue;
				}
			}
			log.info("【发送分润消息】---【结束】-----");
		} catch (Exception e) {
			log.error("【发送分润消息】---【异常】-----{}", e);
		}
	}
	
	/**
	 * 发送再次复投消息
	 * @param tradeId 流水号
	 * @param reList 复投消息集合
	 */
	public void newDoRepeat(String tradeId,List<RepeatInfo> reList) {
		log.info("【再次复投消息】---【开始】-----");
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			log.info("【再次复投消息】---【params】-----{}", reList.toString());
			// 根据交易订单构建 发送消息体
			for (RepeatInfo tf : reList) {
				try {
					// 调用再次复投
					log.info("【再次复投消息】---【调用前】-----{}", tf.toString());
					result = activityService.saveActivityRepeat(tf);
					log.info("【再次复投消息】---【调用结束】-----");
				} catch (Exception e) {
					log.error("【再次复投消息】---【异常】-----{}", e);
					result.put("result",
							(ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "exception", "再次复投消息异常！", "", "01"));
				} finally {
					log.info("【再次复投消息】---【结果为】-----result={}", result.toString());
					ResultInfo res = (ResultInfo) result.get("result");
					if (ResultInfo.ERROR.equals(res.getState())) {
						log.error("【再次复投消息】---【失败】-----code={},msg={}", res.getCode(), res.getMessage());
						ExceptionCommission exc = new ExceptionCommission();
						exc.setTradeId(tradeId);
						exc.setUserId(tf.getUserId());
						exc.setServiceName("multilevelRebateServiceImpl");					
						exc.setInputParams(tf.toString());
						exc.setQueryTime(DateUtil.getTime());
						exc.setErrorCode(res.getCode());
						exc.setErrorMessage(res.getMessage());
						exc.setReserve1("03"); // 复投
						saveErrLog(exc);
					}
				}
			}
			log.info("【发送分润消息】---【结束】-----");
		} catch (Exception e) {
			log.error("【发送分润消息】---【异常】-----{}", e);
		}
	}
	
	/**
	 * 更新公排收益
	 * @param tradeId 流水号
	 * @param rateSet 更新公排收益集合
	 * @param activityId 活动id
	 */
	public void newAddRete(String tradeId,Set<Integer> rateSet, Integer activityId) {
		log.info("【更新公排收益】---【开始】-----");
		try {
			if(rateSet.size() > 0){
				log.info("【更新公排收益】---【params】-----{},activityId={}", rateSet.toString(), activityId);
				activityService.updateActivitySalesVolume(activityId, rateSet);	
			}
			log.info("【更新公排收益】---【调用结束】-----");
		} catch (Exception e) {
			log.error("【更新公排收益】---【异常】-----{}", e);
		}
		log.info("【更新公排收益】---【结束】-----");
	}

	/**
	 * 发送分润消息
	 *
	 * @param tflist
	 *            交易集合
	 */
	public void sendMsgByTf(List<TransactionFlowPo> tfList) {
		log.info("【发送分润消息】---【开始】-----");
		try {
			if (tfList.size() <= 0) {
				log.error("【发送分润消息】---【构建参数异常】----");
			}
			// 根据交易订单构建 发送消息体
			for (TransactionFlowPo tf : tfList) {
				try {
					if ("02".equals(tf.getType())) {
						SysMessage msg = CommMsgUtil.getMsgForComm(h5Domain, tf.getUserId(), tf.getPayPrice(),
								tf.getId(), "01");
						log.info("【发送分润消息】---【消息】-----" + msg.toString());
						sysMessageService.insert(msg);
						if(tf.getTicket() != null) {
							SysMessage meg = CommMsgUtil.getMsgForComm(h5Domain, tf.getUserId(), tf.getTicket(),
									tf.getId(), "02");
							log.info("【发送粮票消息】---【粮票】---userId={}---meg={}", tf.getUserId(), meg);
							sysMessageService.insert(meg);
						}
					}
				} catch (Exception e) {
					log.error("【发送分润消息】---【异常】-----{}", e);
					continue;
				}
			}
			log.info("【发送分润消息】---【结束】-----");
		} catch (Exception e) {
			log.error("【发送分润消息】---【异常】-----{}", e);
		}
	}

	/**
	 * push分润消息
	 *
	 * @param list
	 *            push消息集合
	 */
	public void pushMsg(List<PushMsg> list) {
		log.info("【push信息】---【开始】-----");
		// 根据 发送消息体
		for (PushMsg params : list) {
			try {
				log.info("【push信息】---【params】---{}---{}", params.getUserId(), params.getMsg());
				appPushService.sendToAllAlias(new String[] { "" + params.getUserId() }, params.getMsg());
			} catch (Exception e) {
				log.error("【push信息】---【异常】-----{}", e);
				continue;
			}
		}
		log.info("【push信息】---【结束】-----");
	}

	/**
	 * push分润消息
	 *
	 * @param list
	 *            push消息集合
	 */
	public void pushMsgByTf(List<TransactionFlowPo> tfList) {
		log.info("【push信息】---【开始】-----");
		// 根据 发送消息体
		for (TransactionFlowPo tf : tfList) {
			try {
				if ("02".equals(tf.getType())) {
					Message msg = CommMsgUtil.getPushMsgForComm(h5Domain, tf.getPayPrice(), tf.getId(), "01");
					log.info("【push信息】---【params】---{}---{}", tf.getUserId(), msg);
					appPushService.sendToAllAlias(new String[] { "" + tf.getUserId() }, msg);
					if(tf.getTicket() != null) {
						Message mes = CommMsgUtil.getPushMsgForComm(h5Domain, tf.getTicket(), tf.getId(), "02");
						log.info("【push信息】---【粮票】---userId={}---msg={}", tf.getUserId(), mes);
						appPushService.sendToAllAlias(new String[] { "" + tf.getUserId() }, mes);
					}
				}
			} catch (Exception e) {
				log.error("【push信息】---【异常】-----{}", e);
				continue;
			}
		}
		log.info("【push信息】---【结束】-----");
	}

	/**
	 * 保存异常日志
	 *
	 * @param exc
	 *            异常日志
	 */
	public void saveErrLog(ExceptionCommission exc) {
		log.info("【保存异常日志】---【开始】-----");
		try {
			if (exc != null) {
				log.info("【保存异常日志】---【params】-----" + exc.toString());
				commBackLogServiceImpl.newCommBackLog(exc);
				log.info("【保存异常日志】---【成功】-----");
			} else {
				log.info("【保存异常日志】---【入参为null】-----");
			}
		} catch (Exception e) {
			log.error("【保存异常日志】---【异常】-----{}", e);
		} finally {
			log.info("【保存异常日志】---【结束】-----");
		}

	}

	/**
	 * 构建消息push对象
	 *
	 * @author Administrator
	 */
	public class PushMsg {
		private Integer userId;
		private Message msg;

		public Integer getUserId() {
			return userId;
		}

		public void setUserId(Integer userId) {
			this.userId = userId;
		}

		public Message getMsg() {
			return msg;
		}

		public void setMsg(Message msg) {
			this.msg = msg;
		}

	}
}
